/*
 * $RCSfile: AgentParser.java,v $
 * $Revision: 1.1 $
 * $Date: 2015-06-02 16:33:25 $
 *
 * Copyright (C) 2008 Skin, Inc. All rights reserved.
 *
 * This software is the proprietary information of Skin, Inc.
 * Use is subject to license terms.
 */
package com.skin.demon;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

import com.skin.util.IO;

/**
 * <p>Title: AgentParser</p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2006</p>
 * @author xuesong.net
 * @version 1.0
 */
public class AgentParser {
    /**
     * @param args
     */
    public static void main(String[] args) {
        try {
            String content = IO.toString(AgentParser.class.getResourceAsStream("test.txt"));
            ClassInfo classInfo = parseClassInfo(content);

            System.out.println(classInfo.getName());
            System.out.println(classInfo.getLocation());
            System.out.println(classInfo.getLocations());
            List<MethodInfo> methods = classInfo.getMethodInfoList();

            if(methods != null) {
                for(MethodInfo methodInfo : methods) {
                    System.out.println("-----------------------------");
                    System.out.println(methodInfo.getClassName());
                    System.out.println(methodInfo.getMethodName());
                    System.out.println(methodInfo.getModifiers());
                    System.out.println(methodInfo.getReturnType());
                    System.out.println(methodInfo.getSignature());
                    System.out.println(methodInfo.getDescription());
                }
            }
        }
        catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * @param content
     * @return List<String>
     */
    public static List<String> list(String content) {
        return list(content, "\n", true, true);
    }

    /**
     * @param content
     * @return ClassInfo
     */
    public static ClassInfo parseClassInfo(String content) {
        StringReader reader = new StringReader(content);
        BufferedReader buffer = new BufferedReader(reader);

        ClassInfo classInfo = new ClassInfo();
        List<MethodInfo> methods = new ArrayList<MethodInfo>();
        String line = null;

        try {
            while((line = buffer.readLine()) != null) {
                line = line.trim();

                if(line.length() < 1) {
                    continue;
                }

                if(line.startsWith("name=")) {
                    classInfo.setName(line.substring(5));
                    continue;
                }

                if(line.startsWith("location=")) {
                    classInfo.setLocation(line.substring(9));
                    continue;
                }

                if(line.startsWith("locations=")) {
                    List<String> locations = list(line.substring(10), ",", true, true);
                    classInfo.setLocations(locations);
                    continue;
                }

                if(line.startsWith("method=")) {
                    MethodInfo methodInfo = parseMethodInfo(line.substring(7));
                    methodInfo.setClassName(classInfo.getName());
                    methods.add(methodInfo);
                    continue;
                }
            }
        }
        catch(IOException e) {
        }
        classInfo.setMethodInfoList(methods);
        return classInfo;
    }

    /**
     * @param content
     * @return MethodInfo
     */
    private static MethodInfo parseMethodInfo(String content) {
        int i = 0;
        int j = 0;
        int k = 0;
        int length = content.length();
        MethodInfo methodInfo = new MethodInfo();

        while(i < length) {
            j = content.indexOf('=', i);

            if(j < 0) {
                break;
            }

            k = content.indexOf('&', j + 1);

            if(k < 0) {
                k = length;
            }

            String name = content.substring(i, j);
            String value = content.substring(j + 1, k);
            i = k + 1;

            if(name.equals("name")) {
                methodInfo.setMethodName(value);
            }
            else if(name.equals("modifiers")) {
                methodInfo.setModifiers(Integer.parseInt(value));
            }
            else if(name.equals("parameterTypes")) {
                methodInfo.setParameterTypes(list(value, ",", true, true));
            }
            else if(name.equals("returnType")) {
                methodInfo.setReturnType(value);
            }
            else if(name.equals("signature")) {
                methodInfo.setSignature(value);
            }
            else if(name.equals("description")) {
                methodInfo.setDescription(value);
            }
        }
        return methodInfo;
    }

    /**
     * @param source
     * @param delimiter
     * @param trim
     * @param ignoreBlank
     * @return List<String>
     */
    public static List<String> list(String source, String delimiter, boolean trim, boolean ignoreBlank) {
        int s = 0;
        int p = 0;
        String line = null;
        List<String> list = new ArrayList<String>();

        while((p = source.indexOf(delimiter, s)) > -1) {
            if(p > s) {
                line = source.substring(s, p);

                if(trim) {
                    line = line.trim();
                }

                if(!ignoreBlank || line.length() > 0) {
                    list.add(line);
                }
            }
            s = p + delimiter.length();
        }

        if(s < source.length()) {
            line = source.substring(s);

            if(trim) {
                line = line.trim();
            }

            if(!ignoreBlank || line.length() > 0) {
                list.add(line);
            }
        }
        return list;
    }
}
